home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / MacPNG Library 1.02 / pngMacSrc 1.02 / png.1 / ptot / zchunks.c < prev   
Encoding:
C/C++ Source or Header  |  1995-08-29  |  17.5 KB  |  676 lines  |  [TEXT/CWIE]

  1. /*
  2.  * zchunks.c
  3.  *
  4.  * Code for handling deflated chunks (IDAT and zTXt) is naturally
  5.  * much larger than that for all the other chunks, so I move it all
  6.  * here (as well as tEXt, which shares code with zTXt).
  7.  *
  8.  **********
  9.  *
  10.  * HISTORY
  11.  *
  12.  * 95-03-10 Created by Lee Daniel Crocker <lee@piclab.com>
  13.  *          <URL:http://www.piclab.com/piclab/index.html>
  14.  */
  15.  
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19.  
  20. #include "ptot.h"
  21.  
  22. #define DEFINE_ENUMS
  23. #include "errors.h"
  24.  
  25. extern PNG_STATE ps;
  26.  
  27. /*
  28.  * Interlacing tables
  29.  */
  30. static int
  31.     interlace_pattern[8][8] = {
  32.         { 0, 5, 3, 5, 1, 5, 3, 5 },
  33.         { 6, 6, 6, 6, 6, 6, 6, 6 },
  34.         { 4, 5, 4, 5, 4, 5, 4, 5 },
  35.         { 6, 6, 6, 6, 6, 6, 6, 6 },
  36.         { 2, 5, 3, 5, 2, 5, 3, 5 },
  37.         { 6, 6, 6, 6, 6, 6, 6, 6 },
  38.         { 4, 5, 4, 5, 4, 5, 4, 5 },
  39.         { 6, 6, 6, 6, 6, 6, 6, 6 } },
  40.     starting_row[7] =   { 0, 0, 4, 0, 2, 0, 1 },
  41.     starting_col[7] =   { 0, 4, 0, 2, 0, 1, 0 },
  42.     row_increment[7] =  { 8, 8, 8, 4, 4, 2, 2 },
  43.     col_increment[7] =  { 8, 8, 4, 4, 2, 2, 1 };
  44.  
  45. static int zlib_start(void);
  46. static void zlib_end(void);
  47. static void unfilter(int);
  48. static void write_byte(void);
  49. static int repack_tempfiles(void);
  50.  
  51. /*
  52.  * Decode IDAT chunk. Most of the real work is done inside
  53.  * the NEXTBYTE and FLUSH macros that interface with inflate.c.
  54.  */
  55.  
  56. #define IS_ZTXT (PNG_CN_zTXt == ps.current_chunk_name)
  57. #define IS_TEXT (PNG_CN_tEXt == ps.current_chunk_name)
  58. #define IS_IDAT (PNG_CN_IDAT == ps.current_chunk_name)
  59.  
  60. int
  61. decode_IDAT(
  62.     void)
  63. {
  64.     int err, bpp, pass;
  65.     /*
  66.      * Palette chunk must appear before IDAT for palette-
  67.      * based images.  This is technically a fatal error
  68.      * in the PNG, but we will process the image anyway
  69.      * as a grayscale so the user can see _something_.
  70.      */
  71.     if (ps.image->is_palette && (0 == ps.image->palette_size)) {
  72.         print_warning(WARN_NO_PLTE);
  73.         ps.image->is_palette = ps.image->is_color = FALSE;
  74.     }
  75.     ps.got_first_idat = TRUE;
  76.     bpp = ps.image->bits_per_sample / 8;
  77.     if (0 == bpp) bpp = 1;
  78.     ps.byte_offset = ps.image->samples_per_pixel * bpp;
  79.     /*
  80.      * Allocate largest line needed for filtering
  81.      */
  82.     ps.line_size = new_line_size(ps.image, 0, 1);
  83.     ps.this_line = (U8 *)malloc(ps.line_size);
  84.     ps.last_line = (U8 *)malloc(ps.line_size);
  85.  
  86.     if (NULL == ps.this_line || NULL == ps.last_line) {
  87.         err = ERR_MEMORY;
  88.         goto di_err_out;
  89.     }
  90.     memset(ps.this_line, 0, ps.line_size);
  91.     memset(ps.last_line, 0, ps.line_size);
  92.  
  93.     ps.current_row = ps.interlace_pass = ps.line_x = 0;
  94.     ps.cur_filter = 255;
  95.  
  96.     ps.bytes_in_buf = 0L;   /* Required before calling NEXTBYTE */
  97.     ps.bufp = ps.buf;
  98.  
  99.     if (0 != (err = zlib_start())) goto di_err_out;
  100.     if (0 != (err = create_tempfile(0))) goto di_err_out;
  101.  
  102.     if (ps.image->is_interlaced) {
  103.         for (pass = 1; pass <= 6; ++pass) {
  104.             if (0 != (err = create_tempfile(pass)))
  105.               goto di_err_out;
  106.         }
  107.         ps.line_size = new_line_size(ps.image, 0, 8);
  108.     } else {
  109.         ps.line_size = new_line_size(ps.image, 0, 1);
  110.     }
  111.     if (0 != (err = inflate())) goto di_err_out;
  112.  
  113.     close_all_tempfiles();
  114.     err = repack_tempfiles();
  115. di_err_out:
  116.     if (NULL != ps.this_line) free(ps.this_line);
  117.     if (NULL != ps.last_line) free(ps.last_line);
  118.  
  119.     zlib_end();
  120.     return err;
  121. }
  122.  
  123. /*
  124.  * Assume that the next byte to read in the file begins the
  125.  * compressed area of an IDAT or zTXt. Set up the necessary
  126.  * structures for decompression.
  127.  */
  128.  
  129. static int
  130. zlib_start(
  131.     void)
  132. {
  133.     ASSERT(NULL != ps.inf);
  134.     ASSERT(NULL != ps.buf);
  135.  
  136.     ps.sum1 = 1;    /* Precondition Adler checksum */
  137.     ps.sum2 = 0;
  138.     ps.inflate_flags = (NEXTBYTE << 8);
  139.     ps.inflate_flags |= NEXTBYTE;
  140.  
  141.     ps.inflate_window_size =
  142.       1L << (((ps.inflate_flags >> 12) & 0x0F) + 8);
  143.  
  144.     if (ps.inflate_window_size > 32768) return ERR_COMP_HDR;
  145.  
  146.     if ( (0 != (ps.inflate_flags % 31)) ||
  147.       (8 != ((ps.inflate_flags >> 8) & 0x0F)) ||
  148.       (0 != (ps.inflate_flags & 0x0020)) ) return ERR_COMP_HDR;
  149.  
  150.     ps.inflate_window =
  151.       (U8 *)malloc((size_t)(ps.inflate_window_size));
  152.     if (NULL == ps.inflate_window) return ERR_MEMORY;
  153.  
  154.     ps.inflated_chunk_size = 0L;
  155.     return 0;
  156. }
  157.  
  158. /*
  159.  * Clean up decompressor and verify checksum.
  160.  */
  161.  
  162. static void
  163. zlib_end(
  164.     void)
  165. {
  166.     U16 sum1, sum2;
  167.  
  168.     ASSERT(NULL != ps.inf);
  169.     ASSERT(NULL != ps.buf);
  170.  
  171.     if (NULL == ps.inflate_window) return;
  172.     free(ps.inflate_window);
  173.  
  174.     sum2 = NEXTBYTE << 8;
  175.     sum2 |= NEXTBYTE;
  176.     sum1 = NEXTBYTE << 8;
  177.     sum1 |= NEXTBYTE;
  178.  
  179.     if ((sum1 != ps.sum1) || (sum2 != ps.sum2))
  180.       print_warning(WARN_BAD_SUM);
  181. }
  182.  
  183. /*
  184.  * Unfilter the image data byte passed in, and put it into the
  185.  * ps.this_line[] array for write_pixel to find.
  186.  */
  187.  
  188. static void
  189. unfilter(
  190.     int inbyte)
  191. {
  192.     int prediction, pA, pB, pC, dA, dB, dC;
  193.  
  194.     ASSERT(NULL != ps.this_line);
  195.     ASSERT(NULL != ps.last_line);
  196.  
  197.     if (PNG_PF_None == ps.cur_filter) prediction = 0;
  198.     else {
  199.         pA = ((ps.line_x < ps.byte_offset) ? 0 :
  200.           ps.this_line[ps.line_x - ps.byte_offset]);
  201.         pB = ps.last_line[ps.line_x];
  202.         pC = ((ps.line_x < ps.byte_offset) ? 0 :
  203.           ps.last_line[ps.line_x - ps.byte_offset]);
  204.  
  205.         switch (ps.cur_filter) {
  206.         case PNG_PF_Sub:
  207.             prediction = pA;
  208.             break;
  209.         case PNG_PF_Up:
  210.             prediction = pB;
  211.             break;
  212.         case PNG_PF_Average:
  213.             prediction = ((pA + pB) / 2);
  214.             break;
  215.         case PNG_PF_Paeth:
  216.             prediction = pA + pB - pC;
  217.             dA = abs(prediction - pA);
  218.             dB = abs(prediction - pB);
  219.             dC = abs(prediction - pC);
  220.             if (dA <= dB && dA <= dC) prediction = pA;
  221.             else if (dB <= dC) prediction = pB;
  222.             else prediction = pC;
  223.             break;
  224.         default:
  225.             ASSERT(FALSE);
  226.         }
  227.     }
  228.     ps.this_line[ps.line_x] = 0xFF & (inbyte + prediction);
  229. }
  230.  
  231. /*
  232.  * Calculate how many bytes of image data will appear
  233.  * per line of the given image, accounting for the start
  234.  * and increment of the current interlace pass.
  235.  */
  236.  
  237. #define BPS (ps.image->bits_per_sample)
  238. #define BMAX ((1<<BPS)-1)
  239.  
  240. size_t
  241. new_line_size(
  242.     IMG_INFO *image,
  243.     int start,
  244.     int increment)
  245. {
  246.     U32 pixels;
  247.     size_t size;
  248.  
  249.     ASSERT(NULL != image);
  250.     ASSERT(0 != increment);
  251.     ASSERT(start < 8);
  252.  
  253.     pixels = (((image->width - start) - 1) / increment) + 1;
  254.  
  255.     if (BPS < 8) {
  256.         ASSERT(1 == image->samples_per_pixel);
  257.         size = ((BPS * (pixels - 1)) / 8) + 1;
  258.     } else {
  259.         ASSERT(8 == BPS || 16 == BPS);
  260.         size = pixels * image->samples_per_pixel * (BPS / 8);
  261.     }
  262.     return size;
  263. }
  264.  
  265. static void
  266. write_byte(
  267.     void)
  268. {
  269.     U8 *temp, byte;
  270.     /*
  271.      * Advance pointers and handle interlacing.
  272.      */
  273.     if (++ps.line_x >= ps.line_size) {
  274.         /*
  275.          * We've now received all the bytes for a single
  276.          * scanline. Here we write them to the tempfile,
  277.          * unpacking 1, 2, and 4-bit values into whole bytes.
  278.          */
  279.         if (BPS < 8) {
  280.             int pixel, got_bits;
  281.             U32 start, increment;
  282.  
  283.             if (ps.image->is_interlaced) {
  284.                 start = starting_col[ps.interlace_pass];
  285.                 increment = col_increment[ps.interlace_pass];
  286.             } else {
  287.                 start = 0;
  288.                 increment = 1;
  289.             }
  290.             temp = ps.this_line;
  291.             got_bits = 0;
  292.  
  293.             for (ps.current_col = start;
  294.               ps.current_col < ps.image->width;
  295.               ps.current_col += increment) {
  296.  
  297.                 if (got_bits == 0) {
  298.                     byte = *temp++;
  299.                     got_bits = 8;
  300.                 }
  301.                 pixel = (byte >> (8 - BPS)) & BMAX;
  302.                 pixel = (pixel * 255) / BMAX;
  303.  
  304.                 byte <<= BPS;
  305.                 got_bits -= BPS;
  306.  
  307.                 putc(pixel, ps.tf[ps.interlace_pass]);
  308.             }
  309.         } else {
  310.             if (ps.line_size != fwrite(ps.this_line, 1,
  311.               ps.line_size, ps.tf[ps.interlace_pass]))
  312.               error_exit(ERR_WRITE);
  313.         }
  314.         ps.cur_filter = 255;
  315.         ps.line_x = 0;
  316.         temp = ps.last_line;
  317.         ps.last_line = ps.this_line;
  318.         ps.this_line = temp;
  319.  
  320.         if (ps.image->is_interlaced) {
  321.             ps.current_row +=
  322.               row_increment[ps.interlace_pass];
  323.  
  324.             if (ps.current_row >= ps.image->height) {
  325.                 /*
  326.                  * The return here happens after the
  327.                  * last pixel has been read.
  328.                  */
  329.                 if (++ps.interlace_pass > 6) {
  330.                     --ps.interlace_pass;
  331.                     return;
  332.                 }
  333.                 ps.current_row =
  334.                   starting_row[ps.interlace_pass];
  335.                 ps.line_size = new_line_size(ps.image,
  336.                   starting_col[ps.interlace_pass],
  337.                   col_increment[ps.interlace_pass]);
  338.  
  339.                 memset(ps.last_line, 0, ps.line_size);
  340.             }
  341.         } else {
  342.             ++ps.current_row;
  343.         }
  344.     }
  345. }
  346.  
  347. /*
  348.  * The image has now been read into 1 or 7 temp files, at one
  349.  * more bytes per pixel (to simplfy de-interlacing). This
  350.  * function combines them back into a single file, pointed to
  351.  * by the pixel_data_file member of the image structure.
  352.  */
  353.  
  354. static int
  355. repack_tempfiles(
  356.     void)
  357. {
  358.     char filename[FILENAME_MAX];
  359.     FILE *outf;
  360.     U32 row, col;
  361.     size_t bytes;
  362.     int pass, err, byte, bpp;
  363.     U8 *line_buf, *lp;
  364.  
  365.     ASSERT(0 != ps.buf);
  366.     ASSERT(0 != ps.image);
  367.  
  368.     sprintf(filename, "pngdata.tmp");
  369.     ps.image->pixel_data_file =
  370.       (char *)malloc(strlen(filename) + 1);
  371.     if (NULL == ps.image->pixel_data_file) return ERR_MEMORY;
  372.     else strcpy(ps.image->pixel_data_file, filename);
  373.  
  374.     outf = fopen(ps.image->pixel_data_file, "wb");
  375.     if (NULL == outf) return ERR_WRITE;
  376.  
  377.     if (ps.image->is_interlaced) {
  378.         for (pass = 0; pass <= 6; ++pass) {
  379.             if (0 != (err = open_tempfile(pass))) return err;
  380.         }
  381.         bpp = ps.image->samples_per_pixel;
  382.         if (16 == ps.image->bits_per_sample) bpp *= 2;
  383.         bytes = bpp * ps.image->width;
  384.  
  385.         if (NULL == (line_buf = (U8 *)malloc(bytes)))
  386.           return ERR_MEMORY;
  387.  
  388.         for (row = 0; row < ps.image->height; ++row) {
  389.             lp = line_buf;
  390.  
  391.             for (col = 0; col < ps.image->width; ++col) {
  392.                 pass = interlace_pattern[row & 7][col & 7];
  393.                 for (byte = 0; byte < bpp; ++byte) {
  394.                     *lp++ = getc(ps.tf[pass]);
  395.                 }
  396.             }
  397.             ASSERT(bytes == (lp - line_buf));
  398.             fwrite(line_buf, 1, bytes, outf);
  399.         }
  400.     } else {
  401.         if (0 != (err = open_tempfile(0))) return err;
  402.         if (NULL == (line_buf = (U8 *)malloc(IOBUF_SIZE)))
  403.           return ERR_MEMORY;
  404.  
  405.         while (0 < (bytes =
  406.           fread(line_buf, 1, IOBUF_SIZE, ps.tf[0]))) {
  407.             fwrite(line_buf, 1, bytes, outf);
  408.         }
  409.     }
  410.     free(line_buf);
  411.     close_all_tempfiles();
  412.     fclose(outf);
  413.     remove_all_tempfiles();
  414.     return 0;
  415. }
  416.  
  417. #undef BPS
  418. #undef BMAX
  419.  
  420. /*
  421.  * Handle tEXt and zTXt chunks. The keywords listed in ptot.h
  422.  * will be translated to equivalent TIFF tags. Others are just
  423.  * passed on as unkown PNG chunks.
  424.  */
  425.  
  426. #define KW_MAX 80 /* Longest possible matching keyword */
  427.  
  428. int
  429. decode_text(
  430.     void)
  431. {
  432.     int i, err;
  433.     size_t kw_len, val_len;
  434.     char *srcp, *dstp, **address = NULL;
  435.  
  436.     ASSERT(NULL != ps.inf);
  437.     ASSERT(NULL != ps.buf);
  438.     ASSERT(NULL != ps.image);
  439.     ASSERT(IS_ZTXT || IS_TEXT);
  440.  
  441.     get_chunk_data(ps.bytes_remaining);
  442.  
  443.     for (i = 0; i < N_KEYWORDS; ++i) {
  444.         if (0 == strncmp((char *)ps.buf, keyword_table[i], KW_MAX)) {
  445.             address = &ps.image->keywords[i];
  446.             break;
  447.         }
  448.     }
  449.     if (NULL != address) {
  450.         kw_len = strlen((char *)ps.buf);
  451.         if (IS_ZTXT) {
  452.             if (PNG_CT_Deflate != ps.buf[kw_len + 1]) {
  453.                 err = ERR_BAD_PNG;
  454.                 goto dz_err_out;
  455.             }
  456.             ps.bytes_in_buf -= (kw_len + 2);
  457.             ps.bufp = ps.buf + kw_len + 2;
  458.  
  459.             if (0 != (err = create_tempfile(0))) goto dz_err_out;
  460.             zlib_start();
  461.             inflate();
  462.             zlib_end();
  463.             if (0 != (err = open_tempfile(0))) goto dz_err_out;
  464.  
  465.             ps.buf[0] = '\0';
  466.             ps.buf[1] = getc(ps.tf[0]);
  467.             kw_len = 0;
  468.             ps.bytes_in_buf = 2;
  469.             ps.bytes_remaining = ps.inflated_chunk_size - 1;
  470.         }
  471.         *address = (char *)malloc((size_t)(ps.bytes_remaining +
  472.           ps.bytes_in_buf - kw_len));
  473.  
  474.         dstp = *address;
  475.         val_len = (size_t)(ps.bytes_in_buf - (kw_len + 1));
  476.         srcp = (char *)ps.buf + kw_len + 1;
  477.  
  478.         while (0 != val_len) {
  479.             memcpy(dstp, srcp, val_len);
  480.             srcp = (char *)ps.buf;
  481.             dstp += val_len;
  482.             if (0 != ps.bytes_remaining) {
  483.                 if (IS_ZTXT) {
  484.                     val_len = fread(ps.buf, 1, IOBUF_SIZE,
  485.                       ps.tf[0]);
  486.                     ps.bytes_remaining -= val_len;
  487.                 } else {
  488.                     val_len = get_chunk_data(ps.bytes_remaining);
  489.                 }
  490.             } else val_len = 0;
  491.         }
  492.         *dstp = '\0';
  493.         err = 0;
  494.     } else err = copy_unknown_chunk_data();
  495.  
  496. dz_err_out:
  497.     close_all_tempfiles();
  498.     return err;
  499. }
  500.  
  501. /*
  502.  * Copy unknown but copy-safe chunk.
  503.  */
  504.  
  505. int
  506. copy_unknown_chunk_data(
  507.     void)
  508. {
  509.     int err;
  510.     U8 small_buf[10];
  511.     char fname[FILENAME_MAX];
  512.     U32 output_crc;
  513.     FILE *outf;
  514.  
  515.     ASSERT(NULL != ps.buf);
  516.     ASSERT(NULL != ps.image);
  517.  
  518.     if (NULL == ps.image->png_data_file) {
  519.         sprintf(fname, "pngextra.tmp");
  520.         ps.image->png_data_file =
  521.           (char *)malloc(strlen(fname) + 1);
  522.         if (NULL == ps.image->png_data_file) return ERR_MEMORY;
  523.         strcpy(ps.image->png_data_file, fname);
  524.     }
  525.     if (NULL == (outf = fopen(ps.image->png_data_file, "ab")))
  526.       return ERR_WRITE;
  527.  
  528.     BE_PUT32(small_buf, ps.bytes_remaining + ps.bytes_in_buf);
  529.     BE_PUT32(small_buf+4, ps.current_chunk_name);
  530.     output_crc = 0xFFFFFFFFL;
  531.     output_crc = update_crc(output_crc, ps.buf+4, 4);
  532.  
  533.     err = ERR_WRITE;
  534.  
  535.     if (8 != (fwrite(small_buf, 1, 8, outf))) goto cu_err_out;
  536.  
  537.     if (0 != ps.bytes_in_buf) {
  538.         output_crc = update_crc(output_crc, ps.buf,
  539.           ps.bytes_in_buf);
  540.         if (ps.bytes_in_buf != (U32)fwrite(ps.buf, 1,
  541.           (size_t)(ps.bytes_in_buf), outf)) goto cu_err_out;
  542.     }
  543.     while (0 != ps.bytes_remaining) {
  544.         get_chunk_data(ps.bytes_remaining);
  545.         output_crc = update_crc(output_crc, ps.buf,
  546.           ps.bytes_in_buf);
  547.         if (ps.bytes_in_buf != fwrite(ps.buf, 1,
  548.               (size_t)(ps.bytes_in_buf), outf)) goto cu_err_out;
  549.         ps.bytes_remaining -= ps.bytes_in_buf;
  550.     }
  551.     BE_PUT32(small_buf, output_crc ^ 0xFFFFFFFFL);
  552.     if (4 != (fwrite(small_buf, 1, 4, outf))) goto cu_err_out;
  553.  
  554.     err = 0;
  555. cu_err_out:
  556.     fclose(outf);
  557.     return err;
  558. }
  559.  
  560. /*
  561.  * These next functions are required for interfacing with
  562.  * Mark Adler's inflate.c.  fill_buf() is called by
  563.  * NEXTBYTE when the I/O buffer is empty. It knows about
  564.  * split IDATs and deals with them specially. These two
  565.  * functions are used by zTXt as well.
  566.  */
  567.  
  568. U8
  569. fill_buf(
  570.     void)
  571. {
  572.     int err;
  573.  
  574.     ASSERT(NULL != ps.buf);
  575.     ASSERT(-1 == ps.bytes_in_buf);
  576.     ASSERT(IS_ZTXT || IS_IDAT);
  577.  
  578.     if (0 == ps.bytes_remaining) {
  579.         /*
  580.          * Current IDAT is exhausted. Continue on to the next
  581.          * one. Only IDATs can be split this way.
  582.          */
  583.         if (IS_ZTXT) return ERR_BAD_PNG;
  584.         if (0 != (err = verify_chunk_crc())) return err;
  585.  
  586.         if (0 != (err = get_chunk_header())) return err;
  587.         if (!IS_IDAT) return ERR_EARLY_EOI;
  588.     }
  589.     ps.bufp = ps.buf;
  590.     ps.bytes_in_buf = (S32)fread(ps.buf, 1,
  591.       (size_t)min(IOBUF_SIZE, ps.bytes_remaining), ps.inf);
  592.  
  593.     ps.bytes_remaining -= ps.bytes_in_buf;
  594.     if (0 == ps.bytes_in_buf) return ERR_READ;
  595.     ps.crc = update_crc(ps.crc, ps.buf, ps.bytes_in_buf);
  596.  
  597.     --ps.bytes_in_buf;
  598.     return *ps.bufp++;
  599. }
  600.  
  601. /*
  602.  * Flush uncompressed bytes from inflate window. This function
  603.  * is used for both IDAT and zTXt chunks.
  604.  */
  605.  
  606. void
  607. flush_window(
  608.     U32 size)
  609. {
  610.     U8 *wp, byte;
  611.     U32 length, sum1, sum2;
  612.     int loopcount;
  613.  
  614.     ASSERT(NULL != ps.inflate_window);
  615.     ASSERT(size > 0 && size <= ps.inflate_window_size);
  616.     ASSERT(IS_ZTXT || IS_IDAT);
  617.     /*
  618.      * Compute Adler checksum on uncompressed data, then write.
  619.      * We can safely delay the mod operation for 5552 bytes
  620.      * without overflowing our 32-bit accumulators.
  621.      */
  622.     wp = ps.inflate_window;
  623.     length = size;
  624.     sum1 = ps.sum1;
  625.     sum2 = ps.sum2;
  626.  
  627.     ASSERT(sum1 < 65521);
  628.     ASSERT(sum2 < 65521);
  629.  
  630.     while (length > 0) {
  631.         loopcount = (length > 5552) ? 5552 : length;
  632.         length -= loopcount;
  633.  
  634.         do {
  635.             sum1 += *wp++;
  636.             sum2 += sum1;
  637.         } while (--loopcount);
  638.  
  639.         sum1 %= 65521;
  640.         sum2 %= 65521;
  641.     }
  642.     ps.sum1 = (U16)sum1;
  643.     ps.sum2 = (U16)sum2;
  644.     /*
  645.      * Write uncompressed bytes to output file.
  646.      */
  647.     ps.inflated_chunk_size += size;
  648.     if (IS_ZTXT) {
  649.         fwrite(ps.inflate_window, 1, (size_t)size, ps.tf[0]);
  650.     } else {
  651.         wp = ps.inflate_window;
  652.         length = size;
  653.  
  654.         do {
  655.             byte = *wp++;
  656.  
  657.             if (255 == ps.cur_filter) {
  658.                 ps.cur_filter = byte;
  659.  
  660.                 if (ps.cur_filter > 4) {
  661.                     print_warning(WARN_FILTER);
  662.                     ps.cur_filter = 0;
  663.                 }
  664.             } else {
  665.                 unfilter(byte);
  666.                 write_byte();
  667.             }
  668.         } while (--length);
  669.     }
  670. }
  671.  
  672. #undef IS_ZTXT
  673. #undef IS_TEXT
  674. #undef IS_IDAT
  675.  
  676.